﻿using Abp.Application.Services;
using Abp.Domain.Repositories;
using Admin.Application.Custom.ReportForms.Dto; 
using AutoMapper.Configuration;
using Magicodes.Admin;
using Magicodes.Admin.Custom.TimeLimits;
using Magicodes.Admin.SFOrders;
using Magicodes.Admin.WULINGAddresss;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System.Linq.Expressions;
using System.Linq.Dynamic;
using Magicodes.Admin.Custom.Fins;
using Abp.Application.Services.Dto;
using Castle.Core.Logging;
using Abp.Linq.Extensions;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Magicodes.Admin.Dto;

namespace Admin.Application.Custom.ReportForms
{ 
    public class DaoDaLvReportAppService : AppServiceBase , IDaoDaLvReportAppService
    {
        private readonly IDaoDaLvReporExcelExporter  _daoDaLvReporExcelExporter;
        private readonly IMonthlyListingRepository _monthlyListingRepository;
        private readonly IRepository<WULINGAddress, long> _wulingRepository;
        private readonly ITimeLimitRepository _timeLimitRepository;
        private readonly IRepository<SFOrder, long> _sfOrderRepository;
        private readonly ILogger _logger;
        private readonly IRepository<SFOrderResult, long> _sfOrderResultrepository; 
        private readonly IRepository<SFQiaoRouteStatusBack, long> _orderStatusRepository;
        private readonly IRepository<SFQiaoRouteWaybillRoute, string> _routeRepository;
        public DaoDaLvReportAppService(
            IDaoDaLvReporExcelExporter  daoDaLvReporExcelExporter,
            ITimeLimitRepository  timeLimitRepository,
            IRepository<WULINGAddress, long>  wulingRepository,
            IRepository<SFOrder, long> sfOrderRepository, 
            IRepository<SFOrderResult, long> sfOrderResultrepository, 
            IRepository<SFQiaoRouteStatusBack, long> orderStatusRepository,
            IRepository<SFQiaoRouteWaybillRoute, string> routeRepository,
        ILogger logger,
        IMonthlyListingRepository  monthlyListingRepository
            )
        {
            _daoDaLvReporExcelExporter = daoDaLvReporExcelExporter;
               _timeLimitRepository = timeLimitRepository;
            _sfOrderRepository = sfOrderRepository;
            _wulingRepository = wulingRepository;
            _logger = logger;
            _sfOrderResultrepository = sfOrderResultrepository; 
            _orderStatusRepository = orderStatusRepository;
            _routeRepository = routeRepository;
            _monthlyListingRepository = monthlyListingRepository;
        }

        public async Task<PagedResultDto<DaoDaLvListDto>> GetDaoDaLvReportData(GetDaoDaLvPageListInput input)
        {
            var reList = new List<DaoDaLvListDto>();

            if (input.Month == 0)
                input.Month = DateTime.Now.AddMonths(-1).Month;

            if (input.Year < 2019) 
            input.Year = DateTime.Now.AddMonths(-1).Year;

            var year = input.Year;
            var month = input.Month;

            var monthLists = _monthlyListingRepository.GetAllList(s=>s.SettlementDate.Year==year && s.SettlementDate.Month==month).ToList();

            var query = _sfOrderRepository.GetAll()
                .WhereIf(input.Year > 2018, s => s.CreationTime.Year == input.Year)
                .WhereIf(input.Month > 0, s => s.CreationTime.Month == input.Month);
           

            var addresss = _wulingRepository.GetAllList().ToList();

            var orderStates = _orderStatusRepository.GetAllList()
                .GroupBy(s => s.orderNo)
                .Select(p=>p.OrderByDescending(o=>o.lastTime).First()).ToList();

            var timeLimits = _timeLimitRepository.GetAll().ToList();




            //foreach (var item in monthLists)
            //{

            //}
            var count = await query.CountAsync();
            if (count == 0)
                return new PagedResultDto<DaoDaLvListDto>();
            var orders = query
              .OrderBy(input.Sorting)
              .PageBy(input)
              .ToList();
              
            foreach (var item in orders)
            {
               
                var orderStatesTemp = orderStates.FirstOrDefault(s=>s.orderNo==item.Id+"");

                var monthListTemp = monthLists.FirstOrDefault(s => s.WaybillNumber== orderStatesTemp?.waybillNo);

                if (monthListTemp == null) continue;
                var addressTemp = addresss.First(s=>s.ServiceStationCode==item.ServiceStationCode);

                //签收时间
                var signeTime = Convert.ToDateTime(monthListTemp?.TimeOfSigningAndReceiving);

                //时间差
                var timeSpan = (signeTime - item.CreationTime);
                //实际到达天数
                int days = timeSpan.Days;
                if (days < 1)
                    days = 0;

               //要求到达天数
               var timeLimitTemp= timeLimits.FirstOrDefault(s=> monthListTemp!=null&& monthListTemp .ReceivingAddress.StartsWith(s.Area.Substring(2)) );
                var limitDay = timeLimitTemp != null ? timeLimitTemp.LimitDay : 0;
                if ((timeSpan.TotalHours % 24) > 0)
                    days += 1;
                var temp = new DaoDaLvListDto {
                    StartDate = item.CreationTime,
                    waybillNo = orderStatesTemp?.waybillNo,
                    ShippingNumber = item.ShippingNumber,
                    Province = monthListTemp?.DestinationProvinceName,
                    ServiceStationCode = item.ServiceStationCode,
                    ServiceStationName = addressTemp.ServiceStationName,
                    ReceiverAddress = addressTemp.ReceiverAddress,
                    ContactPhoneNumber = addressTemp.ContactPhoneNumber,
                    NumberOfCases = Convert.ToInt32(monthListTemp?.NumberOfPieces),
                    Weight = Convert.ToDecimal(monthListTemp?.ActualWeight),
                    TotalWeight = Convert.ToDecimal(monthListTemp?.ActualWeight),
                    SettlementAmount = Convert.ToDecimal(monthListTemp?.AmountPayable),
                    ActualTimeOfArrival = days,
                    Signer = monthListTemp?.SignatoryAndRecipient,
                    ToSignForTheTime = signeTime,
                    LimitDay = limitDay,
                       IsDeliver=true,
                        IsTimeout= days<limitDay,
                         
                };

                reList.Add(temp);
               
            }
            return new PagedResultDto<DaoDaLvListDto>(
                reList.Count,
                reList
                );
             
        }

        public async Task<FileDto> GetDaoDaLvToExcel(int year, int month)
        {
            var reList = new List<DaoDaLvListDto>();

            if (month == 0)
                month = DateTime.Now.AddMonths(-1).Month;

            if (year < 2019)
                year = DateTime.Now.AddMonths(-1).Year;

           

            var monthLists = _monthlyListingRepository.GetAllList(s => s.SettlementDate.Year == year && s.SettlementDate.Month == month).ToList();

            var orders = _sfOrderRepository.GetAllList(s => s.CreationTime.Year == year && s.CreationTime.Month == month).ToList();

            var addresss = _wulingRepository.GetAllList().ToList();

            var orderStates = _orderStatusRepository.GetAllList()
                .GroupBy(s => s.orderNo)
                .Select(p => p.OrderByDescending(o => o.lastTime).First()).ToList();

            var timeLimits = _timeLimitRepository.GetAll().ToList();




            //foreach (var item in monthLists)
            //{

            //}

            foreach (var item in orders)
            {

                var orderStatesTemp = orderStates.FirstOrDefault(s => s.orderNo == item.Id + "");

                var monthListTemp = monthLists.FirstOrDefault(s => s.WaybillNumber == orderStatesTemp?.waybillNo);


                var addressTemp = addresss.First(s => s.ServiceStationCode == item.ServiceStationCode);

                //签收时间
                var signeTime = Convert.ToDateTime(monthListTemp?.TimeOfSigningAndReceiving);

                //时间差
                var timeSpan = (signeTime - item.CreationTime);
                //实际到达天数
                int days = timeSpan.Days;
                if (days < 1)
                    days = 0;

                //要求到达天数
                var timeLimitTemp = timeLimits.FirstOrDefault(s => monthListTemp != null && monthListTemp.DestinationProvinceName.StartsWith(s.Area.Substring(0,2)));
                var limitDay = timeLimitTemp != null ? timeLimitTemp.LimitDay : 0;
                if ((timeSpan.TotalHours % 24) > 0)
                    days += 1;
                var temp = new DaoDaLvListDto
                {
                    StartDate = item.CreationTime,
                    waybillNo = orderStatesTemp?.waybillNo,
                    ShippingNumber = item.ShippingNumber,
                    Province = monthListTemp?.DestinationProvinceName,
                    ServiceStationCode = item.ServiceStationCode,
                    ServiceStationName = addressTemp.ServiceStationName,
                    ReceiverAddress = addressTemp.ReceiverAddress,
                    ContactPhoneNumber = addressTemp.ContactPhoneNumber,
                    NumberOfCases = Convert.ToInt32(monthListTemp?.NumberOfPieces),
                    Weight = Convert.ToDecimal(monthListTemp?.ActualWeight),
                    TotalWeight = Convert.ToDecimal(monthListTemp?.ActualWeight),
                    SettlementAmount = Convert.ToDecimal(monthListTemp?.AmountPayable),
                    ActualTimeOfArrival = days,
                    Signer = monthListTemp?.SignatoryAndRecipient,
                    ToSignForTheTime = signeTime,
                    LimitDay = limitDay,
                    IsDeliver = true,
                    IsTimeout = days < limitDay,

                };

                reList.Add(temp);

            }
            return _daoDaLvReporExcelExporter.ExportToFile(reList);
           
        }
    }
}
